﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Net;
using System.Web.Script.Serialization;

namespace DLV.Library.Utilities
{
    public class OAuthGoogle : OAuthBase
    {
        private string _consumerKey = "";
        private string _consumerSecret = "";
        private string _token = "";
        private string _tokenSecret = "";
        private string _callback = "";
        private string _scope = "";

        #region PublicPropertiies
        public string ConsumerKey { get { return _consumerKey; } set { _consumerKey = value; } }
        public string ConsumerSecret { get { return _consumerSecret; } set { _consumerSecret = value; } }
        public string Token { get { return _token; } set { _token = value; } }
        public string TokenSecret { get { return _tokenSecret; } set { _tokenSecret = value; } }
        public string Callback { get { return _callback; } set { _callback = value; } }
        public string Scope { get { return _scope; } set { _scope = value; } }
        #endregion

        public enum Method { GET, POST };        
        public const string AUTHORIZE = "https://accounts.google.com/o/oauth2/auth";
        public const string ACCESS_TOKEN = "https://accounts.google.com/o/oauth2/token";
        //"https://www.google.com/m8/feeds/contacts/default/full?alt=json";
        //https://www.googleapis.com/buzz/v1/people/me/@self?alt=json
        //https://www.googleapis.com/plus/v1/people/me?alt=json

        public OAuthGoogle(string consumerKey, string consumerSecret, string scope, string callback)
        {
            this.ConsumerKey = consumerKey;
            this.ConsumerSecret = consumerSecret;
            this.Scope = scope;
            this.Callback = callback;
        }

        public string AuthorizationLink
        {
            get { return AUTHORIZE + "?response_type=code&client_id=" + this.ConsumerKey + "&redirect_uri=" + this.Callback + "&scope=" + this.Scope; }
        }

        public void GetAccessToken(string code)
        {
            if(string.IsNullOrEmpty(code))
                throw new Exception("The request code was not set");

            string data = "code=" + System.Web.HttpUtility.UrlEncode(code);
            data += "&client_id=" + System.Web.HttpUtility.UrlEncode(this.ConsumerKey);
            data += "&client_secret=" + System.Web.HttpUtility.UrlEncode(this.ConsumerSecret);
            data += "&redirect_uri=" + System.Web.HttpUtility.UrlEncode(this.Callback);
            data += "&grant_type=authorization_code";
            string response = WebRequest(Method.POST, ACCESS_TOKEN, data);
            if (response.Length > 0)
            {
                JavaScriptSerializer js = new JavaScriptSerializer();
                Dictionary<string, string> p = js.Deserialize<Dictionary<string, string>>(response);
                this.Token = p["access_token"];
            }
        }

        public string WebRequest(Method method, string url, string postData)
        {
            HttpWebRequest webRequest = null;
            StreamWriter requestWriter = null;
            string responseData = "";
            if (method == Method.GET && this.Token != "")
            {
                if(url.Contains("?"))
                    url = url + "&access_token=" + this.Token;
                else
                    url = url + "?access_token=" + this.Token;
            }
            webRequest = System.Net.WebRequest.Create(url) as HttpWebRequest;
            webRequest.Method = method.ToString();
            webRequest.ServicePoint.Expect100Continue = false;
            webRequest.Timeout = 20000;            
            if (method == Method.POST)
            {
                webRequest.ContentType = "application/x-www-form-urlencoded";
                //POST the data.
                requestWriter = new StreamWriter(webRequest.GetRequestStream());
                try
                {
                    requestWriter.Write(postData);
                }
                catch
                {
                    throw;
                }
                finally
                {
                    requestWriter.Close();
                    requestWriter = null;
                }
            }
            responseData = WebResponseGet(webRequest);
            webRequest = null;
            return responseData;
        }

        public string WebResponseGet(HttpWebRequest webRequest)
        {
            StreamReader responseReader = null;
            string responseData = "";
            try
            {
                responseReader = new StreamReader(webRequest.GetResponse().GetResponseStream());
                responseData = responseReader.ReadToEnd();
            }
            catch
            {
                throw;
            }
            finally
            {
                webRequest.GetResponse().GetResponseStream().Close();
                responseReader.Close();
                responseReader = null;
            }
            return responseData;
        }
    }
}
